using System;
using ProtoBuf;
using System.IO;
using UnityEngine;
using System.Collections.Generic;
using System.Reflection;
using ExcelConfigs;
using HyuFrameWork;

public class ConfigService : ServiceBase
{
    private static string abName = "configs";
    private static Dictionary<Type, IExtensible> cfgDic;
    protected override void OnInitialize()
    {
        base.OnInitialize();
        cfgDic = new Dictionary<Type, IExtensible>();

        //计时
        DateTime beginTime= DateTime.Now;
        
        LoadAllConfigs();
        
        var time= DateTime.Now-beginTime;
        Debug.Log("载入全部Excels配置，用时："+time.TotalMilliseconds+"ms");
    }
    
    private void LoadAllConfigs()
    {
        var allTypes = Assembly.Load("ExcelConfigs").GetTypes();
        foreach (var type in allTypes)
        {
            var propertyInfo= type.GetProperty("Lists");
            if (propertyInfo == null)
            {
                continue;
            }
            LoadConfig(type);
        }
    }

    public static T Get<T>() where T : class, IExtensible
    {
        if (cfgDic.TryGetValue(typeof(T), out var config))
            return config as T;
        Debug.Log($"{typeof(T)}配置表没有在初始化加载");
        return LoadConfig<T>();
    }

    private static T LoadConfig<T>() where T : IExtensible 
    {
        Type t = typeof(T);
        var resName =  t.Name + ".bytes";
        var textAsset = ServiceManager.Get<ABService>().LoadRes<TextAsset>(abName,resName);
        var bytes = DecompressByZlib(textAsset.bytes);

        T config;
        using (MemoryStream ms = new MemoryStream(bytes))
        {
            config = Serializer.Deserialize<T>(ms);
        }
        cfgDic[typeof(T)] = config;
        return config;
    }
    
    private static void LoadConfig(Type t) 
    {
        var resName =  t.Name + ".bytes";
        var textAsset = ServiceManager.Get<ABService>().LoadRes<TextAsset>(abName,resName);
        var bytes = DecompressByZlib(textAsset.bytes);
        
        using (MemoryStream ms = new MemoryStream(bytes))
        {
            var config = Serializer.Deserialize(t, ms);
            cfgDic[t] = config as IExtensible;
        }
    }
    

    public static byte[] DecompressByZlib(byte[] input) 
    {
        using (MemoryStream ms = new MemoryStream(input))
        {
            var zos = new zlib.ZInputStream(ms);
            using (MemoryStream output = new MemoryStream())
            {
                byte[] temp = new byte[4096];
                int len;
                while((len = zos.read(temp, 0, temp.Length)) > 0) 
                {
                    output.Write(temp, 0, len);
                };
                zos.Close();
                return output.ToArray();
            }
        }
    }
}
